/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cn.com.sixboy.dao.base;

import cn.com.sixboy.dao.DataType;
import cn.com.sixboy.dao.QueryConditionEntity;
import java.sql.Connection;
import java.util.Iterator;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Repository;

/**
 * @author Sam.Zheng <zcl1866@sina.com>
 * @date 2013-4-25 16:30:09
 * @version <v0.1>
 * @copyright SixBoy
 */

@Repository("baseDAO")
public class BaseDAOImplement<T> implements BaseDAO<T> {
	static Logger logger = Logger.getLogger(BaseDAOImplement.class);
	@PersistenceContext
	private EntityManager entityManager;

	/*
	 * 
	 * @param object
	 * 
	 * @return
	 * 
	 * @throws RADPException
	 */

	@Override
	public boolean addEntity(T object) {
		try {
			entityManager.persist(object);
			return true;
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		return false;
	}

	/**
	 * 批量插入数据
	 * 
	 * @param objects
	 * @return
	 */
	public boolean addBatchEntity(List<T> objects) {
		try {

			Iterator iter = objects.iterator();
			int i = 0;
			while (iter.hasNext()) {
				T obj = (T) iter.next();
				entityManager.persist(obj);
				i++;
				if (i > 100) {
					entityManager.flush();
				}
			}

			return true;
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			// logger.error(e.getMessage(), e);
		}
		return false;
	}

	/**
	 * 批量更新数据
	 * 
	 * @param objects
	 * @return
	 */
	@Override
	public boolean updateBatchEntity(List<T> objects) {
		try {

			Iterator iter = objects.iterator();
			int i = 0;
			while (iter.hasNext()) {
				T obj = (T) iter.next();
				entityManager.merge(obj);
				i++;
				if (i > 100) {
					entityManager.flush();
				}
			}

			return true;
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		return false;
	}

	/**
	 * 删除单个实体
	 */
	@Override
	public boolean deleteEntity(T object) {
		try {

			entityManager.remove(entityManager.merge(object));

			return true;
		} catch (Exception e) {
                    e.printStackTrace();
                    logger.error(e.getMessage(), e);
		}
		return false;
	}

	/**
	 * 批量删除
	 * 
	 * @param list
	 * @return
	 * @throws RADPException
	 */
	protected boolean deleteEntity(List<T> list) {
		try {

			for (int i = 0; i < list.size(); i++) {
				T t = entityManager.merge(list.get(i));
				entityManager.remove(t);
			}

			return true;
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		return false;
	}

	/**
	 * 
	 * @param jpql
	 * @param types
	 * @param columns
	 * @param values
	 * @return
	 * @throws RADPException
	 */
	@Override
	public List<T> queryEntities(QueryConditionEntity qce, boolean isNameQuery) {
		String jpql = qce.getJpql();
		try {
			String[] columns = qce.getConditionCoulmns();
			DataType[] types = qce.getConditionCoulmnsTypes();
			Object[] values = qce.getConditionValues();
			Query q = null;
			if (isNameQuery) {
				q = entityManager.createNamedQuery(jpql);
			} else {
				q = entityManager.createQuery(jpql);
			}
			for (int i = 0; i < columns.length; i++) {
				switch (types[i]) {
				case Number:
					q.setParameter(columns[i],
							Integer.parseInt(values[i].toString()));
					break;
				case String:
					q.setParameter(columns[i], values[i].toString());
					break;
				case Date:
					break;
				case Object:
					q.setParameter(columns[i], values[i]);
					break;
				default:
					q.setParameter(columns[i], values[i]);
				}

			}
			return q.getResultList();
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		return null;

	}

	/**
	 * 
	 * 
	 * @param jpql
	 * @param isNameQuery
	 * @return
	 * @throws RADPException
	 */
	@Override
	public List<T> queryAllEntity(String jpql, boolean isNameQuery) {
		try {
			Query q = null;
			if (isNameQuery) {
				q = entityManager.createNamedQuery(jpql);
			} else {
				q = entityManager.createQuery(jpql);
			}
			return q.getResultList();
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		return null;
	}

	/**
	 * 获取JDBC Connction 连接(不推荐使用)
	 * 
	 * @return
	 */
	protected Connection jdbcConn() {
		Connection connection = entityManager.unwrap(java.sql.Connection.class);
		return connection;
	}

	@Override
	public boolean removeBetchEntity(List entities) {
		try {

			for (int i = 0; i < entities.size(); i++) {
				Object obj = entityManager.merge(entities.get(i));
				entityManager.remove(obj);
				if (i % 100 == 0) {
					entityManager.flush();
				}
			}

			return true;
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		return false;
	}

	@Override
	public boolean updateEntity(Object entity) {
		try {

			entityManager.merge(entity);

			return true;
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			return false;
		}
	}

	@Override
	public T querySingleEntity(String jpql) {
                List list = entityManager.createNamedQuery(jpql).getResultList();
                if(list!=null){
                    return (T) list.get(0);
                }else{
                    return null;
                }
		
	}

	@Override
	public T querySingleEntity(Class c, int primaryKey) {
		return (T) entityManager.find(c, primaryKey);
	}

	@Override
	public List queryEntities(String jpql) {
		Query q = entityManager.createNamedQuery(jpql);
		return q.getResultList();
	}

	@Override
	public List queryEntitiesByOneParam(String jpql, String param, Object value) {
		Query q = entityManager.createNamedQuery(jpql);
		q.setParameter(param, value);
		return q.getResultList();
	}

	@Override
	public T queryEntityByOneParam(String jpql, String param, String value) {
		Query q = entityManager.createNamedQuery(jpql);
		q.setParameter(param, value);
		List list = q.getResultList();
		if (list == null || list.isEmpty()) {
			return null;
		} else {
			return (T) list.get(0);
		}
	}

	@Override
	public List queryEntitiesByNativeSQL(String nativeSql, Class<?> type) {
		Query q = entityManager.createNativeQuery(nativeSql, type);
		return q.getResultList();
	}
        
        @Override
        public void  clear(){
            entityManager.clear();
        }

}
